/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*
 * RemoteInfoDialog.java
 *
 * Created on 09.03.2010, 20:39:17
 */
package org.netbeans.modules.dlight.terminal.ui;

import java.awt.Component;
import java.awt.Toolkit;
import java.util.prefs.Preferences;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JTextField;
import javax.swing.text.JTextComponent;
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory;
import org.netbeans.modules.nativeexecution.api.util.ConnectionManager;
import org.openide.util.NbPreferences;

/**
 *
 * @author Vladimir Voskresensky
 */
public final class RemoteInfoDialog extends javax.swing.JPanel {
    private static final String LAST_SELECTED_HOST = "lastSelectedHost"; // NOI18N

    /** Creates new form RemoteInfoDialog */
    public RemoteInfoDialog(String user) {
        initComponents();
        userField.setText(user);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup1 = new javax.swing.ButtonGroup();
        cbKnownHosts = new javax.swing.JComboBox();
        btnKnownHosts = new javax.swing.JRadioButton();
        btnNewHost = new javax.swing.JRadioButton();
        pnlConnectionInfo = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        userField = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        hostField = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        portField = new javax.swing.JTextField();
        btnDeleteHost = new javax.swing.JButton();

        buttonGroup1.add(btnKnownHosts);
        btnKnownHosts.setSelected(true);
        org.openide.awt.Mnemonics.setLocalizedText(btnKnownHosts, org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.btnKnownHosts.text")); // NOI18N
        btnKnownHosts.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                btnKnownHostsItemStateChanged(evt);
            }
        });

        buttonGroup1.add(btnNewHost);
        org.openide.awt.Mnemonics.setLocalizedText(btnNewHost, org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.btnNewHost.text")); // NOI18N
        btnNewHost.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                btnNewHostItemStateChanged(evt);
            }
        });

        pnlConnectionInfo.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "NewHostInfoTitle"))); // NOI18N

        jLabel1.setLabelFor(userField);
        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.jLabel1.text")); // NOI18N

        userField.setText(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.userField.text")); // NOI18N
        userField.setToolTipText(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.userField.toolTipText")); // NOI18N
        userField.setInputVerifier(new NonEmpty());

        jLabel2.setLabelFor(hostField);
        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.jLabel2.text")); // NOI18N

        hostField.setText(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.hostField.text")); // NOI18N
        hostField.setToolTipText(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.hostField.toolTipText")); // NOI18N
        hostField.setInputVerifier(new NonEmpty());

        jLabel3.setLabelFor(portField);
        org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.jLabel3.text")); // NOI18N

        portField.setColumns(4);
        portField.setText(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.portField.text")); // NOI18N
        portField.setToolTipText(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.portField.toolTipText")); // NOI18N
        portField.setInputVerifier(new IntVerifier(portField));

        javax.swing.GroupLayout pnlConnectionInfoLayout = new javax.swing.GroupLayout(pnlConnectionInfo);
        pnlConnectionInfo.setLayout(pnlConnectionInfoLayout);
        pnlConnectionInfoLayout.setHorizontalGroup(
            pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
            .addGroup(pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(pnlConnectionInfoLayout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jLabel1)
                        .addComponent(jLabel2)
                        .addComponent(jLabel3))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(userField, javax.swing.GroupLayout.DEFAULT_SIZE, 364, Short.MAX_VALUE)
                        .addComponent(hostField, javax.swing.GroupLayout.DEFAULT_SIZE, 226, Short.MAX_VALUE)
                        .addComponent(portField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addContainerGap()))
        );
        pnlConnectionInfoLayout.setVerticalGroup(
            pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 117, Short.MAX_VALUE)
            .addGroup(pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(pnlConnectionInfoLayout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel1)
                        .addComponent(userField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(hostField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabel2))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel3)
                        .addComponent(portField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
        );

        userField.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.userField.AccessibleContext.accessibleName")); // NOI18N
        hostField.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.hostField.AccessibleContext.accessibleName")); // NOI18N
        portField.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.portField.AccessibleContext.accessibleName")); // NOI18N

        btnDeleteHost.setText(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.btnDeleteHost.text")); // NOI18N
        btnDeleteHost.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnDeleteHostActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pnlConnectionInfo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(btnKnownHosts)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(cbKnownHosts, 0, 254, Short.MAX_VALUE))
                            .addComponent(btnNewHost))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnDeleteHost)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cbKnownHosts, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btnKnownHosts)
                    .addComponent(btnDeleteHost))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnNewHost)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlConnectionInfo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void btnKnownHostsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_btnKnownHostsItemStateChanged
        if (java.awt.event.ItemEvent.SELECTED == evt.getStateChange()) {
            selectMode(true);
        }
    }//GEN-LAST:event_btnKnownHostsItemStateChanged

    private void btnNewHostItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_btnNewHostItemStateChanged
        if (java.awt.event.ItemEvent.SELECTED == evt.getStateChange()) {
            selectMode(false);
        }
    }//GEN-LAST:event_btnNewHostItemStateChanged

  private void btnDeleteHostActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeleteHostActionPerformed
    ExecutionEnvironment selected = (ExecutionEnvironment) cbKnownHosts.getSelectedItem();
    if (selected != null) {
        ConnectionManager.getInstance().deleteConnectionFromRecentConnections(selected);
        cbKnownHosts.removeItem(selected);
        if (cbKnownHosts.getItemCount() == 0) {
            btnKnownHosts.setEnabled(false);
            btnNewHost.setSelected(true);
        }
        Preferences prefs = NbPreferences.forModule(RemoteInfoDialog.class);
        String eeID = prefs.get(LAST_SELECTED_HOST, "");
        if (!eeID.isEmpty()) {
            ExecutionEnvironment ee = ExecutionEnvironmentFactory.fromUniqueID(eeID);
            if (ee.equals(selected)) {
                prefs.remove(LAST_SELECTED_HOST);
                last = null;
            }
         }
    }
  }//GEN-LAST:event_btnDeleteHostActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnDeleteHost;
    private javax.swing.JRadioButton btnKnownHosts;
    private javax.swing.JRadioButton btnNewHost;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JComboBox cbKnownHosts;
    private javax.swing.JTextField hostField;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel pnlConnectionInfo;
    private javax.swing.JTextField portField;
    private javax.swing.JTextField userField;
    // End of variables declaration//GEN-END:variables

    private ExecutionEnvironment last;
    public ExecutionEnvironment getExecutionEnvironment() {
        if (btnKnownHosts.isSelected()) {
            last = (ExecutionEnvironment) cbKnownHosts.getSelectedItem();
        } else {
            if (userField.getText().isEmpty() || hostField.getText().isEmpty()) {
                return null;
            }

            int port = 22;

            if (!portField.getText().isEmpty()) {
                try {
                    port = Integer.parseInt(portField.getText());
                } catch (NumberFormatException ex) {
                }
            }

            last = ExecutionEnvironmentFactory.createNew(userField.getText(), hostField.getText(), port);
        }
        Preferences prefs = NbPreferences.forModule(RemoteInfoDialog.class);
        prefs.put(LAST_SELECTED_HOST, ExecutionEnvironmentFactory.toUniqueID(last));
        return last;
    }

    private void fillHosts() {
        cbKnownHosts.removeAllItems();
        for (ExecutionEnvironment ee : ConnectionManager.getInstance().getRecentConnections()) {
            cbKnownHosts.addItem(ee);
        }
        boolean hasKnown = cbKnownHosts.getItemCount() > 0;
        btnKnownHosts.setEnabled(hasKnown);
        if (hasKnown) {
            if (last != null) {
                cbKnownHosts.setSelectedItem(last);
            }
            btnKnownHosts.setSelected(true);
        } else {
            btnNewHost.setSelected(true);
        }
        selectMode(hasKnown);
    }

    private void selectMode(boolean knownHosts) {
        cbKnownHosts.setEnabled(knownHosts);
        btnDeleteHost.setEnabled(knownHosts);
        Component[] components = pnlConnectionInfo.getComponents();
        for (Component component : components) {
            component.setEnabled(!knownHosts);
        }
    }

    public void init() {
        if (last == null) {
            Preferences prefs = NbPreferences.forModule(RemoteInfoDialog.class);
            String eeID = prefs.get(LAST_SELECTED_HOST, "");
            if (!eeID.isEmpty()) {
                last = ExecutionEnvironmentFactory.fromUniqueID(eeID);
            }
        }
        fillHosts();
    }

    private static final class IntVerifier extends InputVerifier {

        private final JTextField tf;

        public IntVerifier(JTextField tf) {
            this.tf = tf;
        }

        @Override
        public boolean verify(JComponent input) {
            try {
                Integer.valueOf(tf.getText());
                return true;
            } catch (NumberFormatException numberFormatException) {
                Toolkit.getDefaultToolkit().beep();
                return false;
            }
        }
    }

    private static final class NonEmpty extends InputVerifier {

        public NonEmpty() {
        }

        @Override
        public boolean verify(JComponent input) {
            if (input instanceof JTextComponent) {
                JTextComponent tf = (JTextComponent) input;
                return !tf.getText().isEmpty();
            }

            return true;
        }
    }
}
